package io.renren.modules.oss.service.impl;

import io.renren.common.utils.FileUtil;
import io.renren.common.utils.PropertiesUtil;
import io.renren.modules.oss.constant.UploadConstant;
import io.renren.modules.oss.service.FileUpLoadSrv;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileItemFactory;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.multipart.commons.CommonsMultipartFile;
import sun.misc.BASE64Decoder;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileOutputStream;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.text.SimpleDateFormat;
import java.util.*;

@Service
public class FileUpLoadImpl implements FileUpLoadSrv {
	
	static BASE64Decoder decoder = new BASE64Decoder();//base64类，此类为特殊类（因为jdk的原因，请谷歌）

	@Override
	public Map<String, String> write(HttpServletRequest request, String fileKey, String modelName, String uuid)
			throws Exception {
		MultipartHttpServletRequest rm = (MultipartHttpServletRequest) request;
		//获取文件
		CommonsMultipartFile file = (CommonsMultipartFile) rm
				.getFile("imageFile");
		if(null != file && null != file.getFileItem().getName()){
			return write(file, uuid);
		}
		return null;
	}
	
	
	/**
	 * 该项目上传文件的主要方法
	 */
	@SuppressWarnings("finally")
	@Override
	public Map<String, String> write(MultipartFile cm_file, String uuid) throws Exception {
		
		Map<String,String> result = null;
		String fileName = "";
		String name = cm_file.getOriginalFilename();
		System.out.println("********name*******"+name);
		String fileType = name.substring(name.lastIndexOf(".") + 1, name.length());
		fileType = fileType.toLowerCase();
		//生成名字
		//如果是图片，可能是批量上传，如果是视频或语音，为单独上传，命名规则不同
		Random rand = new Random();
		fileName=name.substring(0,name.indexOf("."))+uuid+"_"+String.valueOf(rand.nextInt(1000))+"."+fileType;
		System.out.println("********fileName*******"+fileName);
		String path = "/" + fileName;//根据项目传过来的值，进行上传后文件存放的文件夹路径的组合
		String realPath = PropertiesUtil.getProperties_1(UploadConstant.ROOT_UPLOAD_FILE_PATH, UploadConstant.RESOURCES_URL); //读取配置文件中的信息
		StringBuffer file_path = new StringBuffer(realPath)
							.append("/").append(fileName);//根据项目信息，进行上传后文件存放的具体路径组合
		//写文件到硬盘
		FileOutputStream out = null;
		FileChannel fc = null;//使用nio中的信道
		
		try {
			if (!new File(realPath.toString()).exists()) {//检查是否此文件夹存在，如果不存在，则创建文件夹
				new File(realPath.toString()).mkdirs();
			}
			if(!new File(file_path.toString()).exists()){//检查是否此文件存在，如果不存在，则创建文件
				new File(file_path.toString().substring(0,file_path.lastIndexOf("/"))).mkdirs();
			}
			out = new FileOutputStream(new File(file_path.toString()));
			fc = out.getChannel();//获取信道
			
            ByteBuffer buf = ByteBuffer.wrap(cm_file.getBytes());//将上传文件转化为二进制流

            int length = 0;
            while ((length = fc.write(buf)) != 0) {//开始写入文件
            }
		} catch (Exception e) {
			e.printStackTrace();
			//删除文档目录及文件信息 
			FileUtil.deleteDirectory(path.toString());
			throw e;
		}finally {
			if(fc != null){
				fc.close();//信道关闭
			}
			if(null != out){
				out.close();//流关闭
			}

			
		}	
		//上传成功后，将生成文件的文件路径和文件名称返回
		result = new HashMap<String, String>();
		result.put("filePath", file_path.toString());
		result.put("fileName", fileName);
		return result;
}


	@Override
	public String getSuffix(String origFileName) throws Exception {
		return origFileName.substring(origFileName.lastIndexOf("."), origFileName.length());
	}

	@Override
	public Map<String, Object> upload(HttpServletRequest request, HttpServletResponse response, String uploadType,
			String referId, String path) throws Exception {
		String rootPath = UploadConstant.RESOURCES_URL;
		// 文件保存目录URL
		String filePath =path+"/";
		// 最大文件大小  
	     long maxSize = 1000000;  
	     
	     response.setContentType("text/html; charset=UTF-8");  
	     
	     if (!ServletFileUpload.isMultipartContent(request)) {  
	         return getError("请选择文件。");  
	     }  
	     
	     SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");  
	     String ymd = sdf.format(new Date());  
	     filePath += ymd + "/";  
	     File dirFile = new File(rootPath+filePath);  
	     if (!dirFile.exists()) {  
	         dirFile.mkdirs();  
	     } 
	     
	     // 检查目录  
	     File uploadDir = new File(rootPath+filePath);  
	     if (!uploadDir.isDirectory()) {  
	         return getError("上传目录不存在。");  
	     }  
	     // 检查目录写权限  
	     if (!uploadDir.canWrite()) {  
	         return getError("上传目录没有写权限。");  
	     }  
	      
	     
	     return uploadFile(request, response, maxSize, uploadType,filePath,rootPath,referId);  
	}

	@Override
	public void downLoadFile(HttpServletRequest request, HttpServletResponse response, String filePath, String fileName)
			throws Exception {
		
	}
	
	private Map<String, Object> getError(String message) throws Exception {  
	       Map<String, Object> msg = new HashMap<String, Object>();  
	       msg.put("error", 1);  
	       msg.put("message", message);  
	       return msg;  
	}  
	
	/**
	 * 上传文件
	 * @param request
	 * @param response
	 * @param maxSize 文件最大限制
	 * @param uploadType 上传模块类型(文件夹名称)
	 * @param saveUrl  图片保存项目路径
	 * @param savePath 图片保存绝对路径
	 * @param referId
	 * @return
	 * @throws Exception
	 */
	private Map<String,Object> uploadFile(HttpServletRequest request,HttpServletResponse response,long maxSize,String uploadType,String filePath,String rootPath,String referId) throws Exception{
		  // 定义允许上传的文件扩展名  
	     HashMap<String, String> extMap = new HashMap<String, String>();  
	     extMap.put("image", "gif,jpg,jpeg,png,bmp");
	    /* extMap.put("flash", "swf,flv");
	     extMap.put("media", "swf,flv,mp3,wav,wma,wmv,mid,avi,mpg,asf,rm,rmvb");  
	     extMap.put("file", "doc,docx,xls,xlsx,ppt,htm,html,txt,zip,rar,gz,bz2");  */
		 FileItemFactory factory = new DiskFileItemFactory();  
	     ServletFileUpload upload = new ServletFileUpload(factory);  
	     upload.setHeaderEncoding("UTF-8");  
	     List<?> items = upload.parseRequest(request);  
	     Iterator<?> itr = items.iterator();  
	     while (itr.hasNext()) {  
	         FileItem item = (FileItem) itr.next();  
	         String fileName = item.getName();  
	         if (!item.isFormField()) {  
	             // 检查文件大小  
	             if (item.getSize() > maxSize) {  
	                 return getError("上传文件大小超过限制。");  
	             }
	             // 检查扩展名  
	             String fileExt = fileName.substring(  
	                     fileName.lastIndexOf(".") + 1).toLowerCase();  
	             if (!Arrays.<String> asList(extMap.get(uploadType).split(","))
	                     .contains(fileExt)) {  
	                 return getError("上传文件扩展名是不允许的扩展名。\n只允许"  
	                         + extMap.get(uploadType) + "格式。");  
	             }  

	             String newFileName = referId + "_"  
	                     + new Random().nextInt(1000) + "." + fileExt;  
	             try {  
	                 File uploadedFile = new File(rootPath+filePath+newFileName);  
	                 item.write(uploadedFile);  
	             } catch (Exception e) {  
	                 return getError("上传文件失败。");  
	             }  

	             Map<String, Object> msg = new HashMap<String, Object>();  
	             msg.put("error", 0); 
	             msg.put("fileUrl",filePath+newFileName);
	             msg.put("message", "上传成功！");
	             return msg;  
	         }  
	     } 
	     return null;
	}

}
